Programs written in a first computer language sometimes call procedures written in a second computer language. A call from a program written in a first computer language to a routine written in a second computer language is referred to as an external callout. The program written in the second computer language is referred to as an external routine. Typically, the first and second computer languages support equivalent data types.
External callouts from routines written in a first computer language to routines written in a second computer language are more problematic when the second computer language does not support data types equivalent to one or more data types of the first computer language. For example, in PL/SQL™, a procedural database language available from Oracle corporation, a BINARY—INTEGER variable can specify any integer value but can also be null. Thus, each such variable is represented by a data structure that shares an integer value and a null flag. The corresponding C integer types (e.g. long, short) cannot represent a null value, and therefore do not have a null flag. Similarly, a PL/SQL™ variable of type VARCHAR2 has an associated LENGTH and MAXIMUM LENGTH, whereas the corresponding C string data type does not.
If it were desired to provide an external call to a C procedure from a PL/SQL routine, in order to communicate attribute information associated with PL/SQL™ variables to the C procedure, the parameter list of the C procedure could be designed with one or more additional (“attribute”) parameters for storing the attribute information. These attribute parameters would have to be appropriately set before each call to the C procedure and examined upon return from the C procedure call. For example, consider an external C routine that performs an operation based upon input data represented by a PL/SQL™ variable of the BINARY—INTEGER data type, and that can modify the received value (including setting to null), and that has the following prototype:                foo(x long, x—null—flag short)where x is a “long” integer value in C and x—null—flag is a “short” integer value in C that serves as a flag to indicate whether the input value x is supposed to be null. No input value supplied for x can be used to indicate null because all possible values of x represent valid integers.        
Each call to foo from the PL/SQL program must do the following:                1. pass in a value for the x—null—flag parameter to indicate to the C procedure whether or not the PL/SQL integer variable passed in for the x parameter is null (e.g. x—null—flag=1 indicates null, x—null—flag=0 indicates not null);        2. upon return from the call, checking the value returned for the x—null—flag parameter, and if the value is −1, setting the PL/SQL integer variable passed in for the x parameter to null.        
One possible approach for passing the required attribute information between a PL/SQL program and C routine is the “hard-coded” approach. In the hard-coded approach, the PL/SQL programmer provides code that explicitly sets the appropriate attribute parameters before each call to an external procedure, and examines the attribute parameters after each call.
The hard-coded approach is tedious and error-prone. For example, before each call to the procedure foo defined above, the PL/SQL programmer provides the code needed to perform some testing and setting of parameter variables. The following (where X1 and X2 are PL/SQL integers passed in as first and second parameters on the call to foo):                IF (X1 IS NULL) THEN                    X2:=−1                        ELSE                    X2=0;                        END IF;In addition, upon return from each call to the procedure foo the PL/SQL programmer needs to perform some testing like the following:        IF (X2=−1) THEN                    X1:=NULL;                        END IF;        
Even if the problems of programmer tedium and error were tolerable, the above hard-coded approach might not provide a general solution, given that some types of attribute information might not be accessible to the PL/SQL™ programmer. For example, there is currently no means for the PL/SQL™ programmer to determine the MAXLEN associated with a PL/SQL™ variable. For these types of attributes, it is not possible for the programmer to determine what attribute values to send to the external routine.
Finally, given that PL/SQL™ is an interpretive language, the hard-coded approach involves increasing the amount of code that must be interpreted at runtime, which in turn, adversely impacts performance.
Based on the foregoing, it is clearly desirable to provide a method which reduces the tedium and error-proneness associated with programmer supplied code that explicitly sets and tests attribute parameter values before and after, respectively, each external callout. It is further desirable to provide a method of communicating to an external routine attribute information not available to the programmer. Finally, it is desirable to provide a method that reduces the adverse impact upon performance associated with the hard-coded approach and resulting from an increased amount of code to be interpreted at runtime.